Notebook NHibernate |
Alex van Buitenen |
This is not a NHibernate tutorial or Quick Reference.
It is just my personal notebook for NHibernate.
Which version of NHibernate to use for which version of Viasual Studio/.NET
Framework?
see
http://en.wikipedia.org/wiki/NHibernate
"NHibernate 3.0 released
Yesterday, Fabio announced the release of NHibernate 3.0 General Availability.
Go get it!
The previous official release of NHibernate was version 2.1.2, just over 1 year
ago.
Since then, the team has made a ton of improvements and bug fixes.
Most importantly, NHibernate now targets .NET 3.5, allowing us to use lambda
expressions and LINQ.
This has led to an explosion of new ways to configure and query."
Bron: http://nhforge.org/blogs/nhibernate/archive/2010/12/05/nhibernate-3-0-released.aspx
downloads at http://sourceforge.net/projects/nhibernate/files/NHibernate/
What does "GA" mean in the dowload versions?
General availability (GA) General availability (GA) is the point where all
necessary commercialization activities have been completed and the software has
been made available to the general market either via the web or physical media.
Bron: http://en.wikipedia.org/wiki/Software_release_life_cycle
Notice how NHibernate detected the modification
to the name and manager properties of the first Employee
(Fred) and automatically updated the database. We’ve taken advantage of a
NHibernate feature called
automatic dirty checking: This feature saves us the effort of explicitly asking
NHibernate to update the
database when we modify the state of an object. Similarly, you can see that the
new Employee (Bill) was
saved when it was associated with the first Employee. This feature is called
cascading save: It saves us the
effort of explicitly making the new object persistent by calling Save(),
as long
as it’s reachable by an already
persistent object (Bill). Also notice that the ordering of the SQL statements
isn’t the same as the order in which
we set fields of the object. NHibernate uses a sophisticated algorithm to
determine an efficient ordering that
avoids database foreign key constraint violations but is still sufficiently
predictable to the user. This feature is
called transactional write-behind.
An instance of ISession is lightweight and is
inexpensive to create and destroy. This is important because your application
will need to create and destroy
sessions all the time, perhaps on every ASP.NET page request. NHibernate
sessions are not thread safe and
should by design be used by only one thread at a time.
NHibernate (and many other ORM implementations) defers the execution of SQL statements. An INSERT statement isn’t usually executed when the application calls ISession.Save(); an UPDATE isn’t immediately issued when the application calls Item.AddBid(). Instead, the SQL statements are usually issued at the end of a transaction. This behavior is called write-behind, as we mentioned earlier.
creation of an ISessionFactory is extremely expensive.
We’ve already discussed the role of the where
clause in expressing restriction. Often, you’ll need to
apply restriction criteria to multiple associated classes (joined tables). If we
want to do this using an
HQL from clause join, we need to assign an alias to the joined class:
from Item item
join item.Bids bid
where item.Description like '%part%'
and bid.Amount > 100
This query assigns the alias item to the class Item and the alias bid to the
joined Item’s bids. We then
use both aliases to express our restriction criteria in the where clause.
If you happen to be using the ITransaction API, you don't need to worry about this step. It will be performed implicitly when the transaction is committed. Otherwise you should call Session.Flush() to ensure that all changes are synchronized with the database.
A call to ISession.Close() marks the end of a session. The main implication of Close() is that the ADO.NET connection will be relinquished by the session.
Pagination is a commonly used technique, and
you’ve probably seen it in action several times. For
example, an eCommerce web site may display lists of products over a number of
pages, each showing
only 10 or 20 products at a time. Typically, users navigate to next or previous
pages by clicking
appropriate links in the page. When writing data access code for this scenario,
the developers needed
to work out how to show the correct page of records at any given time – and
that’s what pagination is
all about.
In NHibernate, both the IQuery and ICriteria interfaces make pagination simple,
as demonstrated
below:
IQuery query =
session.CreateQuery("from User u order by u.Name asc");
query.SetFirstResult(0);
query.SetMaxResults(10);
The call to SetMaxResults(10) limits the query result set to the first 10
objects selected by the
database. What if we wanted to get some results for the next page?
ICriteria crit = session.CreateCriteria(typeof(User));
crit.AddOrder( Order.Asc("Name") );
crit.SetFirstResult(10);
crit.SetMaxResults(10);
IList<User> results = crit.List<User>();
Starting from the 10th object, we retrieve the next 10 objects. Note that there
is no standard way to
express pagination in SQL, and each database vendor often provides a different
syntax and approach.
Fortunately, NHibernate knows the tricks for each vendor, so paging is very
easily done regardless of
your your particular database.
See also
http://stackoverflow.com/questions/1651723/nhibernate-paging-with-sql-server
Have read a parent object with NHibernate.
parent has many-to-one relationship with child.
When the parent object is read, the child object is filled correct.
NHibernate mapping as follows:
<class name="Parent" table="tbl_Parent"
lazy="false" >
<id name="ParentId">
<column name="ParentId" />
<generator class="native" />
</id>
<many-to-one name="Child" column="ChildId" lazy="false" class="Child" />
...
</class>
C# code as follows:
string query = "from Parent";
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();
So far, so good.
Now I want to include a field from the child in
the selection query of the parent.
string query = "from Parent where Child.Field = 1";
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();
Error: multi-part identifier "Parent.Child" could not be bound
Solved by:
string query = "Select Parent from Parent Parent
join Parent.Child Child";
query += " WHERE Child.Field = 1"
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();
"by using UniqueResult I tell NHibernate that I expect only one record to
return. If more than one record is returned by the HQL query then an exception
is raised."
Source:
http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/01/your-first-nhibernate-based-application.aspx